package cn.turboinfo.fuyang.api.domain.mini.usecase.account;

import cn.turboinfo.fuyang.api.domain.common.service.account.CompanyAccountService;
import cn.turboinfo.fuyang.api.domain.common.service.wechat.WechatService;
import cn.turboinfo.fuyang.api.domain.common.usecase.AbstractUseCase;
import cn.turboinfo.fuyang.api.entity.common.enumeration.account.AccountStatus;
import cn.turboinfo.fuyang.api.entity.common.enumeration.account.AccountType;
import cn.turboinfo.fuyang.api.entity.common.enumeration.account.RelationType;
import cn.turboinfo.fuyang.api.entity.common.fo.wechat.WechatAuthResult;
import cn.turboinfo.fuyang.api.entity.common.pojo.account.CompanyAccount;
import cn.turboinfo.fuyang.api.entity.common.pojo.account.CompanyAccountCreator;
import cn.turboinfo.fuyang.api.entity.common.pojo.account.CompanyAccountUpdater;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import net.sunshow.toolkit.core.qbean.helper.component.request.QBeanUpdaterHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Positive;
import java.util.List;
import java.util.Optional;

@Slf4j
@RequiredArgsConstructor
@Component
public class MiniCompanyAccountAuthUseCase extends AbstractUseCase<MiniCompanyAccountAuthUseCase.InputData, MiniCompanyAccountAuthUseCase.OutputData> {
    private final CompanyAccountService companyAccountService;
    private final WechatService wechatService;

    @Override
    protected OutputData doAction(InputData inputData) {
        Long companyId = inputData.getCompanyId();
        String code = inputData.getCode();
        String realname = inputData.getRealname();
        Optional<CompanyAccount> optionalCompanyAccount = companyAccountService.getByCompanyIdAndType(companyId, AccountType.PERSONAL_OPENID);

        try {
            WechatAuthResult result = wechatService.auth(code);
            String openid = result.getOpenid();

            if (optionalCompanyAccount.isPresent()) {
                CompanyAccount companyAccount = optionalCompanyAccount.get();
                companyAccount.setAccount(openid);
                companyAccount.setName(realname);

                CompanyAccountUpdater.Builder builder = CompanyAccountUpdater.builder(companyId);

                QBeanUpdaterHelper.copyPropertiesToUpdateBuilder(builder, CompanyAccountUpdater.class, companyAccount);

                companyAccountService.update(companyAccount);
            } else {
                CompanyAccountCreator creator = CompanyAccountCreator.builder()
                        .withCompanyId(companyId)
                        .withAccount(openid)
                        .withCustomRelation(StringUtils.EMPTY)
                        .withRelationType(RelationType.BRAND)
                        .withName(realname)
                        .withType(AccountType.PERSONAL_OPENID)
                        .withStatus(AccountStatus.INIT)
                        .build();
                companyAccountService.save(creator);
            }


        } catch (Exception e) {
            log.error("微信授权失败: {}", e.getMessage());
        }

        List<CompanyAccount> companyAccountList = companyAccountService.findByCompanyId(inputData.getCompanyId());

        return OutputData.builder()
                .accountList(companyAccountList)
                .build();
    }

    @EqualsAndHashCode(
            callSuper = true
    )
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class InputData extends AbstractUseCase.InputData {

        @NotNull(
                message = "企业ID不能为空"
        )
        @Positive
        private Long companyId;

        @NotNull(
                message = "编码不能为空"
        )
        private String code;

        /**
         * 真实姓名
         */
        @NotBlank(
                message = "真实姓名不能为空"
        )
        private String realname;
    }

    @Getter
    @Setter
    @Builder
    public static class OutputData extends AbstractUseCase.OutputData {
        private List<CompanyAccount> accountList;
    }
}
